


#include "..\Common\MilkshapeModel.h"
#include "..\Common\Main.h"
#include "..\Common\Vector3.h"
//#include "..\Common\Matrix3x3.h"
#include <stdio.h>
using namespace Engine;


App app;


BasicModel *pModel = NULL;												// Holds The Model Data


float yRot  = 0.0f;

AUX_RGBImageRec *LoadBMP(const char *Filename)						// Loads A Bitmap Image
{
	FILE *File=NULL;												// File Handle

	if (!Filename)													// Make Sure A Filename Was Given
	{
		return NULL;												// If Not Return NULL
	}

	File=fopen(Filename,"r");										// Check To See If The File Exists

	if (File)														// Does The File Exist?
	{
		fclose(File);												// Close The Handle
		return auxDIBImageLoad(Filename);							// Load The Bitmap And Return A Pointer
	}

	return NULL;													// If Load Failed Return NULL
}



GLuint LoadGLTexture( const char *filename )						// Load Bitmaps And Convert To Textures
{
	AUX_RGBImageRec *pImage;										// Create Storage Space For The Texture
	GLuint texture = 0;												// Texture ID

	pImage = LoadBMP( filename );									// Loads The Bitmap Specified By filename

	// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
	if ( pImage != NULL && pImage->data != NULL )					// If Texture Image Exists
	{
		glGenTextures(1, &texture);									// Create The Texture

		// Typical Texture Generation Using Data From The Bitmap
		glBindTexture(GL_TEXTURE_2D, texture);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, pImage->sizeX, pImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

		free(pImage->data);											// Free The Texture Image Memory
		free(pImage);												// Free The Image Structure
	}

	return texture;													// Return The Status
}

int DrawGLScene(GLvoid)									// Here's Where We Do All The Drawing
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer
	glLoadIdentity();									// Reset The Current Modelview Matrix
	gluLookAt( 100,100, 100, 0, 0, 0, 0, 1, 0 );
	glRotatef(yRot,0.0f,1.0f,0.0f);									// Rotate On The Y-Axis By yrot
	pModel->Draw();	

	yRot += 1.0f;

	return TRUE;										// Keep Going
}


LRESULT CALLBACK Engine::WndProc(	HWND	hWnd,UINT	uMsg,WPARAM	wParam,	LPARAM	lParam)			
{
	switch (uMsg)									// Check For Windows Messages
	{
		case WM_ACTIVATE:							// Watch For Window Activate Message
		{
			if (!HIWORD(wParam))					// Check Minimization State
			{
				app.mWindow->mActive = TRUE;						// Program Is Active
			}
			else
			{
				app.mWindow->mActive = FALSE;						// Program Is No Longer Active
			}
			return 0;								// Return To The Message Loop
		}

		case WM_SYSCOMMAND:							// Intercept System Commands
		{
			switch (wParam)							// Check System Calls
			{
				case SC_SCREENSAVE:					// Screensaver Trying To Start?
				case SC_MONITORPOWER:				// Monitor Trying To Enter Powersave?
				return 0;							// Prevent From Happening
			}
			break;									// Exit
		}

		case WM_CLOSE:								// Did We Receive A Close Message?
		{
			PostQuitMessage(0);						// Send A Quit Message
			return 0;								// Jump Back
		}

		case WM_KEYDOWN:							// Is A Key Being Held Down?
		{
			app.mKeys[wParam] = TRUE;					// If So, Mark It As TRUE
			return 0;								// Jump Back
		}

		case WM_KEYUP:								// Has A Key Been Released?
		{
			app.mKeys[wParam] = FALSE;					// If So, Mark It As FALSE
			return 0;								// Jump Back
		}

		case WM_SIZE:								// Resize The OpenGL Window
		{
			Engine::ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Height
			return 0;								// Jump Back
		}
	}

	// Pass All Unhandled Messages To DefWindowProc
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

void InitGL()
{

	pModel->LoadModelData("..\\Data\\model.ms3d");
	pModel->ReloadTextures();
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	//return TRUE;		
}

void Initialize(HINSTANCE hInstance)
{
	app.mHinstance = hInstance;
	app.mWindow->mWindowRect->left = 0;
	app.mWindow->mWindowRect->right = 640;
	app.mWindow->mWindowRect->top = 0;
	app.mWindow->mWindowRect->bottom = 480;
	app.mWindow->mTitle = new char[25];
	app.mWindow->mTitle = "Color Window";
	app.mWindow->mBits = 16;
	app.mWindow->mFullScreen = false;
	
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	MSG msg;
	BOOL done = FALSE;

	Initialize(hInstance);

	

	Engine::CreateGLWindow(hInstance, app);
	ReSizeGLScene(app.mWindow->mWindowRect->right, app.mWindow->mWindowRect->bottom);
	pModel = new MilkshapeModel();
	InitGL();

	while(!done)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
			{
				done  = TRUE;
			}
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}else										// If There Are No Messages
		{
			DrawGLScene();
			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
			if (/*(app.mWindow->mActive && !DrawGLScene()) ||*/ app.mKeys[VK_ESCAPE])	// Active?  Was There A Quit Received?
			{
				done=TRUE;							// ESC or DrawGLScene Signalled A Quit
			}
			else									// Not Time To Quit, Update Screen
			{
				SwapBuffers(app.mWindow->mHdc);					// Swap Buffers (Double Buffering)
			}
		}
	}

	//KillGLWindow(hInstance, fullscreen, hRC,hDC,hWnd);
	KillGLWindow(app);
	return msg.wParam;
}